﻿
namespace Mulala.Cavan.Application.MainBoundedContext.ConsignModule
{
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using Mulala.Cavan.Domain.MainBoundedContext.ConsignModule;
    using Mulala.Cavan.Domain.MainBoundedContext.SearchModule;
    using Mulala.Cavan.Domain.Seedwork;
    using Mulala.Cavan.Domain.MainBoundedContext.ProprietorModule;
    using Mulala.Cavan.Domain.MainBoundedContext.NannyModule;
    using Mulala.Cavan.Domain.MainBoundedContext.MulalaModule;
    using Mulala.Cavan.Core.Helper;
    using Mulala.Cavan.Application.MainBoundedContext.ProprietorModule;
    using Mulala.Cavan.Application.MainBoundedContext.NannyModule;
    using Mulala.Cavan.Application.MainBoundedContext.MulalaModule;
    using Mulala.Cavan.Domain.MainBoundedContext.DictionaryModule;
    using Spring.Context;
    using Spring.Context.Support;

    public class ConsignAppService : BaseAppService<Consign, ConsignSearch, IConsignRepository>, IConsignAppService
    {
        private IConsignBidderRepository ConsignBidderRepository { get; set; }
        private IProprietorAppService ProprietorAppService { get; set; }
        private INannyAppService NannyAppService { get; set; }
        private ITagAppService TagAppService { get; set; }

        private IApplicationContext SpringContext = null;

        public ConsignAppService()
        {

        }

        #region IConsignAppService Members

        public override BoolGenericResult<Consign> Add(Consign newConsign)
        {
            this.SpringContext = ContextRegistry.GetContext();
            this.ProprietorAppService = this.SpringContext.GetObject(MulalaAppServiceConst.PROPRIETORAPPSERVICE) as IProprietorAppService;
            BoolGenericResult<Consign> result = new BoolGenericResult<Consign>();
            Proprietor proprietor = this.ProprietorAppService.GetById(newConsign.Proprietor.ID);
            if (null != newConsign.ConsignBidders)
            {
                result = proprietor.PublishConsign(newConsign.Name, newConsign.Age, newConsign.Sex, newConsign.Area, newConsign.Address,
                    newConsign.Experience, newConsign.NecessarySkill, newConsign.FirstSkill, newConsign.SecondSkill,
                    newConsign.ThirdSkill, newConsign.IsMarried, newConsign.HasChildren, newConsign.Degree, newConsign.Salary,
                    newConsign.Type, newConsign.Range, newConsign.ConsignStatus, newConsign.Contact, newConsign.Telephone,
                    newConsign.Remark, newConsign.ConsignBidders); ;
            }
            else
            {
                result = proprietor.PublishConsign(newConsign.Name, newConsign.Age, newConsign.Sex, newConsign.Area, newConsign.Address,
                    newConsign.Experience, newConsign.NecessarySkill, newConsign.FirstSkill, newConsign.SecondSkill,
                    newConsign.ThirdSkill, newConsign.IsMarried, newConsign.HasChildren, newConsign.Degree, newConsign.Salary,
                    newConsign.Type, newConsign.Range, newConsign.ConsignStatus, newConsign.Contact, newConsign.Telephone,
                    newConsign.Remark);
            }

            if (result.IsSuccess)
            {
                this.Repository.Save(result.Object);
            }

            return result;
        }

        public override BoolGenericResult<Consign> Update(Consign changedConsign)
        {
            this.SpringContext = ContextRegistry.GetContext();
            this.ProprietorAppService = this.SpringContext.GetObject(MulalaAppServiceConst.PROPRIETORAPPSERVICE) as IProprietorAppService;
            BoolGenericResult<Consign> result = new BoolGenericResult<Consign>();
            Proprietor proprietor = this.ProprietorAppService.GetById(changedConsign.Proprietor.ID);
            Consign consign = this.Repository.Get(changedConsign.ID);
            result = proprietor.ModifyConsign(consign, changedConsign.Name, changedConsign.Age, changedConsign.Sex, changedConsign.Area,
                                changedConsign.Address, changedConsign.Experience, changedConsign.NecessarySkill, changedConsign.FirstSkill,
                                changedConsign.SecondSkill, changedConsign.ThirdSkill, changedConsign.IsMarried, changedConsign.HasChildren,
                                changedConsign.Degree, changedConsign.Salary, changedConsign.Type, changedConsign.Range, changedConsign.ConsignStatus,
                                changedConsign.Contact, changedConsign.Telephone, changedConsign.Remark);

            if (result.IsSuccess)
            {
                this.Update(consign);
            }

            return result;
        }

        public BoolGenericResult<Consign> UpdateConsignStatus(Consign changedConsign, ConsignIdentifier.ConsignStatus changedConsignStatus)
        {
            this.SpringContext = ContextRegistry.GetContext();
            this.ProprietorAppService = this.SpringContext.GetObject(MulalaAppServiceConst.PROPRIETORAPPSERVICE) as IProprietorAppService;
            BoolGenericResult<Consign> result = new BoolGenericResult<Consign>();
            Proprietor proprietor = this.ProprietorAppService.GetById(changedConsign.Proprietor.ID);
            Consign consign = this.Repository.Get(changedConsign.ID);
            if (changedConsignStatus == ConsignIdentifier.ConsignStatus.IsCanceled)
            {
                result = proprietor.CancelConsign(consign);
            }
            else if (changedConsignStatus == ConsignIdentifier.ConsignStatus.IsDeleted)
            {
                result = proprietor.DeleteConsign(consign);
            }
            else if (changedConsignStatus == ConsignIdentifier.ConsignStatus.IsLocked)
            {
                result = proprietor.LockConsign(consign);
            }
            else if (changedConsignStatus == ConsignIdentifier.ConsignStatus.IsBidding)
            {
                result = proprietor.UnLockConsign(consign);
            }

            if (result.IsSuccess)
            {
                this.Repository.Update(consign);
            }

            return result;
        }

        public BoolGenericResult<ConsignBidder> AddConsignBidder(Consign consign, Nanny nanny)
        {
            this.SpringContext = ContextRegistry.GetContext();
            this.NannyAppService = this.SpringContext.GetObject(MulalaAppServiceConst.NANNYAPPSERVICE) as INannyAppService;
            BoolGenericResult<ConsignBidder> result = new BoolGenericResult<ConsignBidder>();

            Consign bidConsign = this.Repository.Get(consign.ID);
            Nanny bidder = this.NannyAppService.GetById(nanny.ID);

            result = bidder.BidConsign(bidConsign);

            if (result.IsSuccess)
            {
                this.ConsignBidderRepository.Save(result.Object);
            }

            return result;
        }

        public BoolGenericResult<ConsignBidder> AddConsignBidderByProprietor(Consign consign, Nanny nanny, Proprietor proprietor)
        {
            this.SpringContext = ContextRegistry.GetContext();
            this.NannyAppService = this.SpringContext.GetObject(MulalaAppServiceConst.NANNYAPPSERVICE) as INannyAppService;
            this.ProprietorAppService = this.SpringContext.GetObject(MulalaAppServiceConst.PROPRIETORAPPSERVICE) as IProprietorAppService;
            BoolGenericResult<ConsignBidder> result = new BoolGenericResult<ConsignBidder>();

            Consign bidConsign = this.Repository.Get(consign.ID);
            Nanny bidder = this.NannyAppService.GetById(nanny.ID);
            Proprietor designater = this.ProprietorAppService.GetById(proprietor.ID);

            result = designater.DesignateNanny(bidder, bidConsign);

            if (result.IsSuccess)
            {
                this.ConsignBidderRepository.Save(result.Object);
            }
            result.Messages.Add("请求合约成功");
            return result;
        }

        public BoolGenericResult<ConsignBidder> UpdateConsignBidderStatusToCancel(Consign consign, Nanny nanny, bool isToCancel)
        {
            this.SpringContext = ContextRegistry.GetContext();
            this.NannyAppService = this.SpringContext.GetObject(MulalaAppServiceConst.NANNYAPPSERVICE) as INannyAppService;
            BoolGenericResult<ConsignBidder> result = new BoolGenericResult<ConsignBidder>();

            Consign bidConsign = this.Repository.Get(consign.ID);
            Nanny bidder = this.NannyAppService.GetById(nanny.ID);

            if (isToCancel)
            {
                result = bidder.CancelConsign(bidConsign);
            }
            else
            {
                result = bidder.ResumeBidConsign(bidConsign);
            }

            if (result.IsSuccess)
            {
                this.Repository.Update(bidConsign);
                this.ConsignBidderRepository.Update(result.Object);
            }

            return result;
        }

        public BoolGenericResult<ConsignBidder> UpdateConsignBidderStatusToAccept(Consign consign, Nanny nanny)
        {
            this.SpringContext = ContextRegistry.GetContext();
            this.ProprietorAppService = this.SpringContext.GetObject(MulalaAppServiceConst.PROPRIETORAPPSERVICE) as IProprietorAppService;
            consign = this.Repository.Get(consign.ID);
            Proprietor proprietor = consign.Proprietor;
            BoolGenericResult<ConsignBidder> result = proprietor.AcceptBidder(nanny, consign);

            if (result.IsSuccess)
            {
                this.Repository.Update(consign);
                this.ConsignBidderRepository.Update(result.Object);
            }

            return result;
        }

        public IList<Consign> GetConsignsByProprietor(int id)
        {
            ConsignSpecification consignSpecification = new ConsignSpecification();
            consignSpecification.SearchParams.ProprietorID = id;

            IList<Consign> consigns = this.Repository.GetAll(consignSpecification).ToList();

            return consigns;
        }

        public IList<Consign> GetConsignsByCondition(ConsignSearch searchParams, out long total)
        {
            ConsignSpecification consignSpecification = SpecificationFactory.CreateConsignSpecification(searchParams);

            IList<Consign> consigns = this.Repository.GetPageList(out total, consignSpecification);

            return consigns;
        }

        public IList<Consign> GetConsignsBySearch(ConsignSearch searchParams)
        {
            ConsignSpecification consignSpecification = SpecificationFactory.CreateConsignSpecification(searchParams);

            IList<Consign> consigns = this.Repository.GetAll(consignSpecification).ToList();

            return consigns;
        }

        public IList<Consign> GetConsignByKeyword(string keyword, int currentPage, out long total)
        {
            ConsignSpecification consignSpecification = new ConsignSpecification();
            consignSpecification.SearchParams = ParseKeywordToConsignSearch(keyword);

            IList<Consign> consigns = this.Repository.GetPageList(out total, consignSpecification);

            return consigns;
        }

        private ConsignSearch ParseKeywordToConsignSearch(string keywork)
        {
            this.SpringContext = ContextRegistry.GetContext();
            this.TagAppService = this.SpringContext.GetObject(MulalaAppServiceConst.TAGAPPSERVICE) as ITagAppService;
            ConsignSearch consignSearch = new ConsignSearch();
            string[] keywords = StringHelper.ClearExtraSpace(keywork).Split(' ');
            List<int> skillPosition = new List<int>();
            foreach (string kw in keywords)
            {
                TagSearch tagSearch = new TagSearch();
                tagSearch.Text = kw;
                Tag tag = this.TagAppService.GetSingleBySearch(tagSearch);
                PackageConsignSearch(consignSearch, tag, skillPosition);
            }
            consignSearch.SkillPosition = skillPosition.ToArray();

            return consignSearch;
        }

        private ConsignSearch PackageConsignSearch(ConsignSearch consignSearch, Tag tag, List<int> skillPosition)
        {
            if (null != tag)
            {
                if (tag.TagGroup.ID == DictionaryIdentifier.GroupType.NannyExperience.GetHashCode())
                {
                    consignSearch.Experience = tag.ID;
                }
                else if (tag.TagGroup.ID == DictionaryIdentifier.GroupType.NannySalary.GetHashCode())
                {
                    consignSearch.Salary = tag.ID;
                }
                else if (tag.TagGroup.ID == DictionaryIdentifier.GroupType.NannyDegree.GetHashCode())
                {
                    consignSearch.Degree = tag.ID;
                }
                else if (tag.TagGroup.ID == DictionaryIdentifier.GroupType.NannyAge.GetHashCode())
                {
                    consignSearch.Age = tag.ID;
                }
                else if (tag.TagGroup.ID == DictionaryIdentifier.GroupType.NannyType.GetHashCode())
                {
                    consignSearch.Type = (NannyIdentifier.NannyType)int.Parse(tag.Value);
                }
                else if (tag.TagGroup.ID == DictionaryIdentifier.GroupType.NannySkill.GetHashCode())
                {
                    skillPosition.Add(tag.BinaryPosition);
                }
            }
            return consignSearch;
        }

        public BoolResult UpdateConsignBidder(ConsignBidder changedConsignBidder)
        {
            BoolResult result = new BoolResult();
            this.ConsignBidderRepository.Update(changedConsignBidder);

            return result;
        }

        public IList<ConsignBidder> GetConsignsByNanny(int id)
        {
            IList<ConsignBidder> consignBidders = this.ConsignBidderRepository.GetAll(SpecificationFactory.CreateConsignBidderSpecification(ConsignBidderSearchFactory.CreateConsignBidderSearch(id, null))).ToList();

            return consignBidders;
        }

        public IList<ConsignBidder> GetConsignsByCorporation(int id)
        {
            IList<ConsignBidder> consignBidders = this.ConsignBidderRepository.GetAll(SpecificationFactory.CreateConsignBidderSpecification(ConsignBidderSearchFactory.CreateConsignBidderSearch(null, id))).ToList();

            return consignBidders;
        }

        public IList<ConsignBidder> GetConsignBiddersByProprietor(int id)
        {
            IList<ConsignBidder> consignBidders = this.ConsignBidderRepository.GetAll(SpecificationFactory.CreateConsignBidderSpecification(ConsignBidderSearchFactory.CreateConsignBidderSearch(id, ConsignIdentifier.ConsignStatus.IsBidding))).ToList();

            return consignBidders;
        }

        public long GetConsignBidderCount(ConsignBidderSearch search)
        {
            ConsignBidderSpecification specification = SpecificationFactory.CreateConsignBidderSpecification(search);
            return this.ConsignBidderRepository.GetCount(specification);
        }
        #endregion
    }
}
